﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http.Headers;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using YF_Music.Core.Services;
using Microsoft.Extensions.Logging;

namespace YF_Music.Service
{
  public class HttpService : IHttpService
  {
    private readonly HttpClient _client;
    private readonly ILogger<HttpService> _logger;

    public HttpService(HttpClient client, ILogger<HttpService> logger)
    {
      _client = client;
      _logger = logger;
    }

    public async Task<string?> SendJsonRequestAsync(string url, string? jsonData = null, HttpMethod? method = null, int timeoutMs = 5000)
    {
      using var cts = new CancellationTokenSource(timeoutMs);

      var request = new HttpRequestMessage(method ?? HttpMethod.Get, url);
      request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
      request.Headers.UserAgent.ParseAdd("Mozilla/5.0");

      if (!string.IsNullOrWhiteSpace(jsonData))
      {
        request.Content = new StringContent(jsonData, Encoding.UTF8, "application/json");
      }

      try
      {
        using var response = await _client.SendAsync(request, cts.Token);
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadAsStringAsync(cts.Token);
      }
      catch (Exception ex)
      {
        _logger.LogError(ex, $"请求失败: {url}");
        return null;
      }
    }

    public async Task<T?> GetJsonAsync<T>(string url, int timeoutMs = 5000)
    {
      var json = await SendJsonRequestAsync(url, null, HttpMethod.Get, timeoutMs);

      return string.IsNullOrEmpty(json)
          ? default
          : JsonSerializer.Deserialize<T>(json);
    }

    public async Task<string?> DownloadFileAsync(string url, string savePath, int timeoutMs = 10000)
    {
      using var cts = new CancellationTokenSource(timeoutMs);

      try
      {
        using var response = await _client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, cts.Token);
        if (!response.IsSuccessStatusCode)
          return null;

        await using var stream = await response.Content.ReadAsStreamAsync(cts.Token);
        await using var fs = new FileStream(savePath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);

        await stream.CopyToAsync(fs, cts.Token);

        return savePath;
      }
      catch (Exception ex)
      {
        _logger.LogError(ex, $"下载失败: {url}");
        return null;
      }
    }

    public async Task<string?> UploadFileAsync(string url, string filePath, int timeoutMs = 10000)
    {
      using var cts = new CancellationTokenSource(timeoutMs);

      using var content = new MultipartFormDataContent();
      using var fileStream = File.OpenRead(filePath);

      content.Add(new StreamContent(fileStream), "file", Path.GetFileName(filePath));

      try
      {
        using var response = await _client.PostAsync(url, content, cts.Token);
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadAsStringAsync(cts.Token);
      }
      catch (Exception ex)
      {
        _logger.LogError(ex, $"文件上传失败: {url}");
        return null;
      }
    }
  }
}
